
trait Person {
    fn name(&self) -> String;
}
trait Student : Person {
    fn university(&self) -> String;
}

trait IProgrammer {
    fn fav_language(&self)-> String;
}
trait CompSciStudent : IProgrammer + Student {
    fn git_username(&self) -> String;
}

struct Programmer {
    name: &'static str,
    university: &'static str,
    fav_lang: &'static str,
    git_username: &'static str
}



impl IProgrammer for Programmer {
    fn fav_language(&self)-> String{
        String::from(self.fav_lang)
    }
}
impl Person for Programmer {
    fn name(&self) -> String{
        String::from(self.name)
    }
}

impl Student for Programmer {
    fn university(&self) -> String{
        String::from(self.university)
    }
}
impl CompSciStudent for Programmer {
    fn git_username(&self) -> String{
        String::from(self.git_username)
    }
}


//fn comp_sci_student_greeting(student: & dyn CompSciStudent) {
fn comp_sci_student_greeting(student: & impl CompSciStudent) {
    println!(" My name is {} and I attend {}. My favorite language is {}. My Git username is {}",
        student.name(),
        student.university(),
        student.fav_language(),
        student.git_username()
    );
}

pub fn main(){
    let cl =  Programmer { 
        name: "cl", 
        university: "tj", 
        fav_lang: "rust", 
        git_username: "sun"
    };
    comp_sci_student_greeting(&cl);
}
